using System;
using SpellCore;
using System.Collections.Generic;

namespace SpellCenter.Core
{
    sealed public class SpellWordInfo
    {
        private CheckingResult? _status = null;
        private readonly double _suspiciousness;
        private readonly string _word;
        private readonly int _occurenceCount;
      private readonly CorpusIndex _index;

        public SpellWordInfo(CorpusIndex index, string word, int occurrenceCount)
        {
          _index = index;
          _word = word;
          _suspiciousness = 0.0;
          _status = CheckingResult.Unknown;
          _occurenceCount = occurrenceCount;
        }

        public string Word
        {
            get { return _word; }
        }

        public double Suspiciousness
        {
            get { return _suspiciousness; }
        }

        public CheckingResult Status
        {
            get
            {
                if(_status == null)
                {
                  _status = WritingSystemDictionary.GetStatusOfWord(_index.WritingSystemId, Word);
                }
                return (CheckingResult) _status;
            }

            set
            {
                if(value == CheckingResult.Good)
                  WritingSystemDictionary.AddGoodWord(_index.WritingSystemId, Word);
                else if(value == CheckingResult.Bad)
                  WritingSystemDictionary.AddBadWord(_index.WritingSystemId, Word);
                _status = value;
            }
        }

        public string StatusString
        {
            get { return CheckingResultToString(Status); }
            set { _status = StringToCheckingResult(value); }
        }

        public const string STATUS_UNKNOWN = "?";
        public const string STATUS_GOOD = "\u221A"; //square root mark (check mark)
        public const string STATUS_BAD = "X";

        public static string CheckingResultToString(CheckingResult checkingResult)
        {
            switch (checkingResult)
            {
                case CheckingResult.Unknown:
                    return STATUS_UNKNOWN;
                case CheckingResult.Good:
                    return STATUS_GOOD;
                case CheckingResult.Bad:
                    return STATUS_BAD;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        public static CheckingResult StringToCheckingResult(string str)
        {
            switch (str)
            {
                case STATUS_UNKNOWN:
                    return CheckingResult.Unknown;
                case STATUS_GOOD:
                    return CheckingResult.Good;
                case STATUS_BAD:
                    return CheckingResult.Bad;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        #region GetOccurrencesOfWord and OccurrenceCount members

        /// <summary>
        /// </summary>
        /// <param name="resolution">The number of characters before and after the word to include in context</param>
        /// <returns></returns>
      public IEnumerable<WordContext> GetOccurrencesOfWord(int resolution)
      {
        return _index.GetOccurrencesOfWord(Word, resolution);
      }

        /// <summary>
        /// Finds the number of occurences of this Word in the entire corpus
        /// </summary>
        public int OccurrenceCount
        {
            get
            {
                return _occurenceCount;
            }
        }

        #endregion

    }
}